package com.vegetable.modules.service.outbound.impl;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.common.constant.CommonConstant;
import com.vegetable.common.utils.Constant;
import com.vegetable.common.utils.PageUtils;
import com.vegetable.common.utils.Query;
import com.vegetable.common.utils.R;
import com.vegetable.modules.entity.outbound.SalesOrderDetailStock;
import com.vegetable.modules.entity.outbound.SalesOther;
import com.vegetable.modules.entity.outbound.SalesOtherDetail;
import com.vegetable.modules.entity.stock.Stock;
import com.vegetable.modules.mapper.outbound.SalesOtherMapper;
import com.vegetable.modules.service.baseData.IProductsService;
import com.vegetable.modules.service.outbound.ISalesOrderDetailStockService;
import com.vegetable.modules.service.outbound.ISalesOtherDetailService;
import com.vegetable.modules.service.outbound.ISalesOtherService;
import com.vegetable.modules.service.stock.IStockFlowService;
import com.vegetable.modules.service.stock.IStockService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 其他出库表 服务实现类
 * </p>
 *
 * @author wangruijie
 * @since 2024-04-03
 */
@Slf4j
@Service
@AllArgsConstructor
public class SalesOtherServiceImpl extends ServiceImpl<SalesOtherMapper, SalesOther> implements ISalesOtherService {

    private ISalesOtherDetailService detailService;
    // 销售商品明细库存对照表
    private ISalesOrderDetailStockService detailStockService;
    // 产地商品
    private IProductsService productsService;
    // 库存管理
    private IStockService stockService;
    // 库存流水
    private IStockFlowService iStockFlowService;
    /**
     * 其他出库列表查询
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String startTime = (String)params.get("startTime");
        String endTime = (String)params.get("endTime");
        String type = (String)params.get("type");
        // 单号
        String docNo = (String)params.get("docNo");
        IPage<SalesOther> page = this.page(
                new Query<SalesOther>().getPage(params),
                new QueryWrapper<SalesOther>()
                        .between(StringUtils.isNotBlank(startTime), "order_time", startTime, endTime)
                        .like(StringUtils.isNotBlank(docNo),"doc_no", docNo)
                        .eq(StringUtils.isNotBlank(type),"type", type)
                        .orderByDesc("create_time")
        );

        return new PageUtils(page);
    }

    /**
     * 详情其他出库
     * @param id null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    public R detailSalesOther(Long id) {
        SalesOther salesOther = baseMapper.selectById(id);
        if (salesOther == null){
            return R.fail("订单不存在");
        }
        // 查询原订单的商品
        QueryWrapper<SalesOtherDetail> detailQuery = new QueryWrapper();
        detailQuery.eq("sales_id", salesOther.getId());
        List<SalesOtherDetail> details = detailService.getBaseMapper().selectList(detailQuery);
        List<SalesOrderDetailStock> detailStocks = detailStockService.selectByOrderId(salesOther.getId());
        Map<Long, List<SalesOrderDetailStock>> stockMap = detailStocks.stream().collect(Collectors.groupingBy(r -> r.getDetailId()));
        for(Map.Entry<Long, List<SalesOrderDetailStock>> en : stockMap.entrySet()){
            SalesOtherDetail detail = details.stream().filter(el -> el.getId().equals(en.getKey())).findAny().orElse(null);
            if(Objects.isNull(detail)){
                continue;
            }
            detail.setStocks(en.getValue());
        }
        salesOther.setCommodities(details);
        return R.data(salesOther);
    }

    /**
     * 新增其他出库
     * @param salesOther null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R saveSalesOther(SalesOther salesOther) throws Exception {
        // 新增入库采购收货主表
        if (CollectionUtils.isEmpty(salesOther.getCommodities())){
            throw new Exception("商品列表不能为空");
        }
        // 商品总数
        Integer number = 0;
        // 商品总重
        BigDecimal weight = BigDecimal.ZERO;
        BigDecimal cost = BigDecimal.ZERO;
        for (SalesOtherDetail orderDetail: salesOther.getCommodities()) {
            number = number+orderDetail.getNumber();
            weight = weight.add(orderDetail.getWeight());
            if (orderDetail.getCost() != null){
                cost = cost.add(orderDetail.getCost());
            }
        }
        salesOther.setNumber(number);
        salesOther.setWeight(weight);
        salesOther.setCost(cost);
        if (salesOther.getId() == null){
            salesOther.setDocNo(CommonConstant.QTCK+ baseMapper.getNextCode());
            save(salesOther);
        }else {
            // 修改主表数据
            updateById(salesOther);
            // 删除其他费用，商品信息，已经商品下的信息
            deleteMethod(salesOther);
        }
        // 入库采购收货主键
        Long mainId = salesOther.getId();
        // 保存订单下明细
        saveDetailInfo(mainId, salesOther);

        return R.data(mainId);
    }

    /**
     * 保存订单下明细
     * @param mainId
     * @param salesOther
     * @return
     */
    private R saveDetailInfo(Long mainId, SalesOther salesOther){
        // 保存订单下明细
        log.info("保存订单下明细:{}", JSON.toJSONString(salesOther.getDocNo()));
        List<SalesOtherDetail> commodities = salesOther.getCommodities();
        for (SalesOtherDetail deliveryDetail: commodities) {
            deliveryDetail.setId(null);
            deliveryDetail.setSalesId(mainId);
            log.info("保存其他出库商品明细表");
            detailService.save(deliveryDetail);
            List<SalesOrderDetailStock> stocks = deliveryDetail.getStocks();
            if (CollectionUtils.isNotEmpty(stocks)){
                for (SalesOrderDetailStock detailStock:stocks) {
                    detailStock.setOrderId(mainId);
                    detailStock.setDetailId(deliveryDetail.getId());
                }
                log.info("保存其他出库商品对应库存明细表");
                detailStockService.saveBatch(stocks);
            }
        }
        return R.data(mainId);
    }

    /**
     * 提交其他出库
     * @param salesOther null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R submitSalesOther(SalesOther salesOther) throws Exception {
        saveSalesOther(salesOther);
        // 更新出库库存
        saveOutStock(salesOther);
        return R.status(true);
    }

    /**
     * 更新出库 库存
     * @param salesOther null
     * @return void
     * @author wrj
     * @since 2024/3/22 上午11:49
     */
    private void saveOutStock(SalesOther salesOther) throws Exception {

        // 更新出库库存
        for (SalesOtherDetail detail :salesOther.getCommodities()) {

            if (CollectionUtils.isNotEmpty(detail.getStocks())){
                for (SalesOrderDetailStock detailStock :detail.getStocks()) {
                    Stock stock = stockService.getBaseMapper().selectById(detailStock.getStockId());
                    if (stock != null){
                        log.info("其他出库商品出库更新库存，原库存：{}", JSON.toJSONString(stock));
                        BigDecimal cost = stock.getCost();
                        BigDecimal weight = stock.getWeight();
                        BigDecimal price_unit = stock.getCostWeight();
                        BigDecimal changeNum = NumberUtil.equals(stock.getStandard(), BigDecimal.ZERO) ? detailStock.getWeight() : new BigDecimal(detailStock.getNumber());
                        // 累加到第一条
                        stock.setNumber(stock.getNumber() - detailStock.getNumber());
                        weight = weight.subtract(detailStock.getWeight());
                        stock.setWeight(weight);
                        cost = cost.subtract(price_unit.multiply(detailStock.getWeight()));
                        stock.setCost(cost);
                        // 成本/重量
//                        BigDecimal costWeight = stock.getCost().divide(stock.getWeight(), 6, RoundingMode.HALF_UP);
//                        stock.setCostWeight(costWeight);
                        log.info("销售出库商品出库更新库存，新库存：{}", JSON.toJSONString(stock));
                        if (stock.getNumber() >= 0 && stock.getWeight().compareTo(BigDecimal.ZERO) >= 0){
                            stockService.updateById(stock);
                        }else {
//                            stockService.removeById(stock);
                            throw new Exception("库存不够 请重试");
                        }
                        iStockFlowService.addStockFlow(stock, Constant.StockFlowType.OTHER_OUT.getValue(),  changeNum, stock.getStorageOrderNo(), Constant.StockFlowType.OTHER_OUT.getName(), salesOther.getOrderTime());
                    }else {
                        log.info("其他出库商品出库更新库存不存在:{}", detailStock.getStockId());
                        throw new Exception("其他出库：库存id下的库存不存在："+detailStock.getStockId());
                    }

                }
            }
        }
    }

    /**
     * 删除其他出库
     * @param id null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deleteSalesOther(Long id) throws Exception {
        SalesOther salesOther = baseMapper.selectById(id);
        if (salesOther == null){
            throw new Exception("订单不存在");
        }
//        if (salesOther.getState().intValue() != 0){
//            throw new Exception("订单不是未出库状态，不能删除");
//        }
        baseMapper.deleteById(id);
        deleteMethod(salesOther);
        return R.status(true);
    }

    /**
     * 删除主方法
     * @param salesOther
     * @return
     */
    private R deleteMethod(SalesOther salesOther) throws Exception {
        QueryWrapper<SalesOtherDetail> detailQueryWrapper = new QueryWrapper();
        detailQueryWrapper.eq("sales_id", salesOther.getId());
        List<SalesOtherDetail> orderDetails = detailService.getBaseMapper().selectList(detailQueryWrapper);
        if (CollectionUtils.isNotEmpty(orderDetails)){
            for(SalesOtherDetail ds : orderDetails ){
                stockService.releaseStockByDetailId2(ds.getId());
            }

            QueryWrapper<SalesOtherDetail> queryWrapper = new QueryWrapper();
            queryWrapper.eq("sales_id", salesOther.getId());
            log.info("删除其他出库商品明细");
            detailService.getBaseMapper().delete(queryWrapper);
//
//            QueryWrapper<SalesOrderDetailStock> stockQueryWrapper = new QueryWrapper<>();
//            stockQueryWrapper.in("detail_id", detailIds);
//            log.info("删除其他出库商品下的库存关系表数据");
//            detailStockService.getBaseMapper().delete(stockQueryWrapper);
        }
        return R.status(true);
    }
}
